package com.atguigu.spzx.filter;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.atguigu.spzx.feign.user.UserFeignClient;
import com.atguigu.spzx.model.entity.user.UserInfo;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.context.annotation.Lazy;
import org.springframework.core.Ordered;
import org.springframework.http.HttpHeaders;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.Assert;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.net.URI;
import java.util.concurrent.CompletableFuture;


@Component
public class AuthFilter implements GlobalFilter,Ordered{
    AntPathMatcher antPathMatcher=new AntPathMatcher();
    @Lazy
    @Autowired
    private UserFeignClient userFeignClient;

    @SneakyThrows
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        HttpHeaders headers = request.getHeaders();
        String path = request.getPath().toString();
        URI uri = request.getURI();
        //鉴定路径,根据路径是否含auth判断需不需要鉴权.
        boolean match = antPathMatcher.match("/api/**/auth/**", path);
        if (match){
            //需要鉴权
            //需要调用中央权限微服务,user 去根据当前请求token去鉴权.
            System.out.println("需要鉴权:---match:"+match);
            //调用token
            String token = headers.get("token").get(0);
            Assert.notNull(token,"token不能为空");
            //调用user,检查token
            //集成openfeign  请求user服务鉴权.
            UserInfo userInfo = CompletableFuture.supplyAsync(()->{
                //注意openfeign调用是会建立新请求调用服务。
                return userFeignClient.checkUserInfo(token);
            }).get();
            //获取到了用户信息,将信息存入请求头,并将request请求头更新,传入下一个微服务.
            //.mutate方法改变更新信息

            request.mutate().header("userJson", JSON.toJSONString(userInfo, SerializerFeature.BrowserSecure));
            exchange.mutate().request(request);
        }

        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return -1;
    }

/*    @Override
    public int getOrder() {
        return -1;
    }*/
}
